<!-- 
在 Vue 3 中，组件通信是构建复杂应用时的关键部分。组件之间需要通过不同的方式进行数据传递和事件通知。
  1. 父子组件通信
   1.1 父组件向子组件传值（Props）
  父组件可以通过 Props 向子组件传递数据。子组件通过  `props`  接收这些数据。
  父组件：
  <template>
    <ChildComponent :message="parentMessage" />
  </template>

  <script>
  import ChildComponent from './ChildComponent.vue';

  export default {
    data() {
      return {
        parentMessage: '来自父组件的消息',
      };
    },
    components: {
      ChildComponent,
    },
  };
  </script>
  子组件：
  <template>
    <div>{{ message }}</div>
  </template>

  <script>
  export default {
    props: {
      message: String,
    },
  };
  </script>
   1.2 子组件向父组件传值（事件）

  子组件通过  `$emit`  发送事件，父组件可以监听这些事件来获取数据。
  示例：
  子组件：
  <template>
    <button @click="sendMessage">发送消息</button>
  </template>

  <script>
  export default {
    methods: {
      sendMessage() {
        this.$emit('messageSent', '来自子组件的消息');
      },
    },
  };
  </script>
  父组件：
  <template>
    <ChildComponent @messageSent="handleMessage" />
  </template>

  <script>
  export default {
    methods: {
      handleMessage(message) {
        console.log(message);
      },
    },
  };
  </script>
  2. 兄弟组件通信
  兄弟组件之间的通信通常需要通过父组件进行。
   2.1 通过父组件传递数据
  父组件可以将数据从一个子组件传递到另一个子组件。
  示例：
  父组件：
  <template>
    <ChildA @sendData="receiveData" />
    <ChildB :data="sharedData" />
  </template>

  <script>
  import ChildA from './ChildA.vue';
  import ChildB from './ChildB.vue';

  export default {
    data() {
      return {
        sharedData: '',
      };
    },
    methods: {
      receiveData(data) {
        this.sharedData = data;
      },
    },
    components: {
      ChildA,
      ChildB,
    },
  };
  </script>
  3. 全局状态管理
  对于大型应用，使用 Vuex 或 Pinia 等状态管理库可以更方便地管理组件之间的状态。
   3.1 Vuex
  Vuex 是 Vue 的状态管理库，可以在全局范围内管理状态，组件可以通过 getters、actions 和 mutations 来获取和修改状态。
   3.2 Pinia
  Pinia 是 Vue 3 的新一代状态管理库，提供了更轻量和灵活的 API。
  4. 插槽（Slots）
  插槽允许父组件在子组件中插入内容，提供了一种灵活的组件组合方式。
  示例：
  子组件：
  <template>
    <div>
      <slot></slot>
    </div>
  </template>
  父组件：
  <template>
    <ChildComponent>
      <p>这是插入的内容</p>
    </ChildComponent>
  </template>
  5. 事件总线（Event Bus）
  虽然在 Vue 3 中不再推荐使用事件总线，但在某些情况下仍然可以用作组件间通信的方式。可以通过创建一个新的 Vue 实例来实现事件总线。

  总结
  - 父子组件通信：通过 Props 和事件实现。
  - 兄弟组件通信：通过父组件传递数据。
  - 全局状态管理：使用 Vuex 或 Pinia 管理应用状态。
  - 插槽：提供灵活的组件内容插入方式。
  - 事件总线：可用于组件间通信，但不推荐在大型应用中使用。
-->
<template>
  <div class="app">
    <h3>1. 父组件向子组件传值（Props）</h3>
    <sub-content 
      title="我是父组件传递过来的数据" 
      msg="通过 Props 和事件实现。"
      class="active"
    ></sub-content>

    <h3>2. 子组件向父组件传值（事件）</h3>
    <h4>当前计数: {{ counter }}</h4>
    <emit-counter @add="addCounter"></emit-counter>

    <h3>3. 案例练习</h3>
    <h4>展示内容: {{ pageContents[currentIndex] }}</h4>
    <tab-control :titles="['衣服', '鞋子', '裤子']" 
                 @tab-item-click="tabItemClick"
                 :currentIndex="currentIndex"/>

  </div>
</template>

<script setup>
  import { ref } from 'vue';
  import subContent from './components/subContent.vue';
  import emitCounter from './components/emitCounter.vue';
  import tabControl from './components/TabControl.vue.vue';

  const currentIndex = ref(0);
  const pageContents = ref(['衣服', '鞋子', '裤子']);

  const counter = ref(0);
  const addCounter = (count) => {
    counter.value += count;
  }

  const tabItemClick = (index) => {
    currentIndex.value = index;
  }

</script>

<style lang="scss" scoped></style>
